package com.lantosec.hmrp.core.util;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lantosec.hmrp.core.kit.PageVO;
import com.lantosec.hmrp.core.mvc.BaseEntity;
import com.lantosec.hmrp.core.mvc.BaseVO;

import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 杨成宇
 * @version 1.0
 */
public class BeanUtils {
    public static <T extends Object> T mapToObject(Map<String, Object> map, Class<?> beanClass) {
        if (map == null || map.isEmpty())
            return null;
//        Object obj = beanClass.newInstance();
//        Field[] fields = obj.getClass().getDeclaredFields();
//        for (Field field : fields) {
//            int mod = field.getModifiers();
//            if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
//                continue;
//            }
//            field.setAccessible(true);
//            field.set(obj, map.get(field.getName()));
//        }
        try {
            Map<String, Object> newMap = new HashMap<>();
            for (String key : map.keySet()) {
                newMap.put(StringUtils.toCamelCase(key, "_"), map.get(key));
            }
            Object obj = beanClass.newInstance();
            org.apache.commons.beanutils.BeanUtils.populate(obj, newMap);
            return (T) obj;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static <T extends Object> List<T> mapListToObjectList(List<Map<String, Object>> list, Class<?> beanClass) {
        List<T> ret = new ArrayList<>();
        if (list == null || list.isEmpty()) {
            return ret;
        }
        for (Map<String, Object> map : list) {
            ret.add(mapToObject(map, beanClass));
        }
        return ret;
    }

    public static <T extends Object> Map<String, Object> objectToMap(T obj) throws Exception {
        if (obj == null) {
            return null;
        }
        Map<String, Object> map = new HashMap();
        Field[] declaredFields = obj.getClass().getDeclaredFields();
        for (Field field : declaredFields) {
            field.setAccessible(true);
            map.put(field.getName(), field.get(obj));
        }
        return map;
    }

    public static <V extends BaseVO<E>, E extends BaseEntity> E VO2Entity(V vo) {
        return vo.convertToEntity();
    }

    public static <V extends BaseVO<E>, E extends BaseEntity> List<E> VO2Entity(Collection<V> voList) {
        return voList.parallelStream().map(item -> item.convertToEntity()).collect(Collectors.toList());
    }

    public static <V extends BaseVO, E extends BaseEntity<V>> V entity2VO(E entity) {
        return entity.convertToVO();
    }

    public static <V extends BaseVO, E extends BaseEntity<V>> List<V> entity2VO(Collection<E> entityList) {
        return entityList.parallelStream().map(item -> item.convertToVO()).collect(Collectors.toList());
    }

    public static <V extends BaseVO, E extends BaseEntity<V>> PageVO<V> entity2VO(IPage<E> page) {
        PageVO<V> res = new PageVO<V>(page.getCurrent(), page.getSize(), page.getTotal());
        res.setRecords(entity2VO(page.getRecords()));
        return res;
    }

}
